<?php

class TestSelectQueryBuilder extends PHPUnitTest
{

    /**
     * Tests
     */

    public function testSelectQueryBuilderCreatesSimpleQueryString() {
        $selectQueryBuilder = $this->getSelectQueryBuilder();

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals('SELECT * FROM example;', $sqlQuery);
    }

    public function testSelectQueryBuilderSelectsDistinct() {
        $selectQueryBuilder = $this->getSelectQueryBuilder();
        $selectQueryBuilder->isDistinct = true;

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals('SELECT DISTINCT * FROM example;', $sqlQuery);
    }

    public function testSelectQueryBuilderSelectsOneField() {
        $selectQueryBuilder = $this->getSelectQueryBuilder(array('data'));

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals('SELECT data FROM example;', $sqlQuery);
    }

    public function testSelectQueryBuilderSelectsManyField() {
        $selectQueryBuilder = $this->getSelectQueryBuilder(array('id', 'data'));

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals('SELECT id, data FROM example;', $sqlQuery);
    }

    public function testSelectQueryBuilderCanUseCriteria() {
        $selectQueryBuilder = $this->getSelectQueryBuilder(array('id', 'data'));
        $selectQueryBuilder->addCriteria(new Criteria('id', Criteria::EQUAL, '2'));

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals("SELECT id, data FROM example WHERE (id = '2');", $sqlQuery);
    }

    public function testSelectQueryBuilderCanJoinTables() {
        $selectQueryBuilder = $this->getSelectQueryBuilder(array('id', 'data'));
        $selectQueryBuilder->addCriteria(new Criteria('id', Criteria::EQUAL, '2'));
        $selectQueryBuilder->joinTable('test');

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals("SELECT id, data FROM example JOIN test ON (example.id = test.id) WHERE (id = '2');", $sqlQuery);
    }

    public function testSelectQueryBuilderCanOrderByFields() {
        $selectQueryBuilder = $this->getSelectQueryBuilder(array('id', 'data'));
        $selectQueryBuilder->orderBy('id');

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals("SELECT id, data FROM example ORDER BY id ASC;", $sqlQuery);
    }

    public function testSelectQueryBuilderCanLimitRows() {
        $selectQueryBuilder = $this->getSelectQueryBuilder(array('id', 'data'));
        $selectQueryBuilder->addLimit(1, 5);

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals("SELECT id, data FROM example LIMIT 1,5;", $sqlQuery);
    }

    public function testSelectQueryBuilderCanGroupByOneColumn() {
        $fieldCollection = new FieldCollection(array('id', 'data'));
        $selectQueryBuilder = $this->getSelectQueryBuilder($fieldCollection->getFields());
        $selectQueryBuilder->groupByField('data');

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals("SELECT id, data FROM example GROUP BY data;", $sqlQuery);
    }

    public function testSelectQueryBuilderCanGroupByManyColumns() {
        $fieldCollection = new FieldCollection(array('id', 'data'));
        $selectQueryBuilder = $this->getSelectQueryBuilder($fieldCollection->getFields());
        $selectQueryBuilder->groupByFields($fieldCollection->getFields());

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals("SELECT id, data FROM example GROUP BY id, data;", $sqlQuery);
    }

    public function testSelectQueryBuilderCanUseHavingClause() {
        $fieldCollection = new FieldCollection(array('COUNT(id)', 'data'));
        $selectQueryBuilder = $this->getSelectQueryBuilder($fieldCollection->getFields());
        $selectQueryBuilder->groupByField('data');
        $selectQueryBuilder->having(new Criteria('COUNT(id)', Criteria::GREATER_THAN, '1'));

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals("SELECT COUNT(id), data FROM example GROUP BY data HAVING (COUNT(id) > '1');", $sqlQuery);
    }

    public function testSelectQueryBuilderCanBuildComplexQueryWithAllClauses() {
        $fieldCollection = new FieldCollection(array('COUNT(id)', 'data'));
        $selectQueryBuilder = $this->getSelectQueryBuilder($fieldCollection->getFields());
        $selectQueryBuilder->addCriteria(new Criteria('id', Criteria::EQUAL, '2'));
        $selectQueryBuilder->joinTable('test');
        $selectQueryBuilder->groupByField('data');
        $selectQueryBuilder->having(new Criteria('COUNT(id)', Criteria::GREATER_THAN, '1'));
        $selectQueryBuilder->addLimit(1, 2);

        $sqlQuery = $selectQueryBuilder->getSQLQuery();

        $this->assertEquals("SELECT COUNT(id), data FROM example JOIN test ON (example.id = test.id) WHERE (id = '2') GROUP BY data HAVING (COUNT(id) > '1') LIMIT 1,2;", $sqlQuery);
    }

    /**
     * Helpers
     */

    /**
     * @param string[] $fields
     * @param string $tableName
     * @return SelectQueryBuilder
     */
    private function getSelectQueryBuilder($fields = null, $tableName = null) {
        $fields = !$fields ? array('*') : $fields;
        $tableName = !$tableName? 'example' : $tableName;
        $selectQueryBuilder = new SelectQueryBuilder($fields, $tableName);
        return $selectQueryBuilder;
    }

}